/* eslint-disable no-unused-vars */
/* eslint-disable no-use-before-define  */
/* eslint-disable import/no-cycle */
/* eslint-disable no-param-reassign */
import React, { useEffect, useImperativeHandle, useState, forwardRef, useRef } from 'react';
import { Button, Form, Layout, message, Modal, Drawer, Input, Space } from 'antd';
import DesignTool from './designTool';
import DesignProperty from './designProperty';
import DesignHistroy from './designHistory';
import ApiHelper from './api';
import styled from './style.less';//勿删
import DesignContext from './designContext';
import DesignControl from './designControl';
import ToolBarDrap from './common/ToolBarDrap';
import DataSourceScriptList from './datasource/dataSourceScriptList';
import EventScriptList from './event/eventScriptList';
import useSyncCallback from './common/useSyncCallback';
import ControlContextMenu from './common/ControlContextMenu';
import SubFormList from './subform/subFormList';
import ControlUtil from './controls/ControlUtil';


const DesignForm = forwardRef((props, ref) => {
  const { formkey, formtype, formname, children, layout } = props;
  const { subform, formelement, initvalue, defaultform, defaulttoolbar, defaultpackages } = props;
  // 编辑器需要使用的包引用
  const [packages, setPackages] = useState({ ...{ DesignContext, DesignControl }, ...defaultpackages });
  // 控件集合字典
  const [controls, setControls] = useState([]);
  const [isEditState, setIsEditState] = useState(false);
  const [useformData, setUseFormData] = useState({ formkey, formtype, formname, layout });
  // 事件流
  const [eventScripts, setEventScripts] = useState([]);
  const refevent = useRef(null);
  // 数据源
  const [dataSourceScripts, setDataSourceScripts] = useState([]);
  const [dataSourceResults] = useState(new Map());
  const refdatasource = useRef(null);
  // 子表单
  const [subForms, setSubForms] = useState([]);
  const refsubForms = useRef(null);
  // 刷新页面
  const [userefreash, setRefreash] = useState(new Date().getTime());
  // 设计器属性
  const refDesignProperty = useRef(null);
  // 右键菜单
  const refMenu = useRef(null);
  // 历史表单
  const refDesignHistroy = useRef(null);
  // tool工具栏拖拽效果
  const tooldrap = new ToolBarDrap.ToolDrap();
  // 工具栏配置
  const [toolbar, setToolBar] = useState(defaulttoolbar);
  // 加载表单
  const load = function () {
    useformData.formkey === '' ? message.error('formKey未定义') : '';
    if (defaultform != null) {
      loadForm(defaultform);
    } else {
      ApiHelper.getForm(
        useformData.formkey,
        {
          form_key: useformData.formkey,
        },
        (success) => {
          const form = success?.data;
          const form2 = {
            form: form.form || {},
            datasourceResults: form.datasourceResults || new Map(),
            subforms: form.subforms || [],
          };
          loadForm(form2);
        },
        (fail) => {
          console.error(`${useformData.formkey}表单加载失败`);
        },
      );
    }
  };
  // 加载表单
  const loadForm = ({ form, datasourceResults, subforms }) => {
    const datasourceresult = datasourceResults || new Map();
    Object.keys(datasourceresult).forEach((key) => {
      dataSourceResults.set(key, datasourceresult[key]);
    });
    const formJson = JSON.parse(form.form_design_model || '{}');
    setFormProperty(formJson);
    const dataSourceJson = JSON.parse(form.form_design_datasource || '[]');
    setDataSourceScripts(dataSourceJson);
    const eventJson = JSON.parse(form.form_design_event || '[]');
    setEventScripts(eventJson);
    const controlsJson = formJson.controls || [];
    const orderControls = ControlUtil.loadForm2(children, controlsJson);
    // 控件基本初始化
    orderControls.forEach((c) => {
      c.init(openObj());
    });
    setControls(orderControls);
    console.log(`${useformData.formkey}表单加载成功`);
    setSubForms(subforms);
    if (initvalue != null) {
      setJsonValue(initvalue, { controls: orderControls });
    }
    loadDataSource(dataSourceJson, 'page_loading', initvalue);
    pageLoadedCall();
  };
  // 页面加载完成
  const pageLoadedCall = useSyncCallback(() => {
    const loaded = dataSourceScripts.filter((c) => c.loadOrder === 'page_loaded');
    if (loaded != null && loaded.length > 0) {
      loadDataSource(
        loaded,
        null,
        null,
        () => controlPageLoaded(),
        () => controlPageLoaded(),
      );
    } else {
      controlPageLoaded();
    }
  });
  const controlPageLoaded = () => {
    controls.forEach((c) => {
      c.pageloaded(openObj());
    });
  };
  // 加载数据源
  const loadDataSource = function (dataSourceScripts1, filterLoadOrder, initvalue2, successCallback, failCallback) {
    const dataSourceScripts2 = dataSourceScripts1 || [];
    if (dataSourceScripts2.length > 0) {
      let dataSourceScripts3 = dataSourceScripts2;
      if (filterLoadOrder != null) {
        dataSourceScripts3 = dataSourceScripts3.filter((c) => c.loadOrder === filterLoadOrder);
      }
      if (dataSourceScripts3.length > 0) {
        ApiHelper.getDataSource(
          useformData.formkey,
          {
            form_key: useformData.formkey,
            formData: JSON.stringify(initvalue2 || getJsonValue()),
            dataSourceScripts: JSON.stringify(dataSourceScripts3),
          },
          (success) => {
            const results = success?.data || new Map();
            dataSourceScripts3.forEach((s) => {
              dataSourceResults.set(s.name, results[s.name]);
            });
            refreash();
            console.log(`${useformData.formkey}数据源加载成功`, success.data);
            successCallback && successCallback(success);
          },
          (fail) => {
            console.error(`${useformData.formkey}表单数据源加载失败`);
            failCallback && failCallback(fail);
          },
        );
      }
    }
  };
  // 保存表单
  const save = function () {
    ApiHelper.saveForm(
      useformData.formkey,
      {
        form_key: useformData.formkey,
        form_type: useformData.formtype,
        form_name: useformData.formname,
        form_design_type: 0,
        form_design_model: JSON.stringify(getDesignModelJson()),
        form_design_datasource: JSON.stringify(dataSourceScripts),
        form_control_property_model: JSON.stringify(getPropertyJson()),
        form_design_event: JSON.stringify(eventScripts),
      },
      (success) => {
        setIsEditState(false);
        message.info('表单保存成功');
        load();
      },
      (fail) => {
        message.info('表单保存失败');
      },
    );
  };
  // 配置表单属性
  const setFormProperty = function (property) {
    setUseFormData({ ...useformData, ...property });
  };
  // 刷新表单
  const refreash = function () {
    setRefreash(new Date().getTime());
  };
  // 根据标题获取控件
  const getControlByTitle = function (title) {
    let find = null;
    ControlUtil.deepSearchControls(controls, null, (item, parent, index, end) => {
      if (item != null && item.data.title === title) {
        find = item;
        return false;
      }
      return true;
    });
    return find;
  };
  // 刷新控件排序
  const refreshControlsOrder = function (controls2) {
    const controls3 = ControlUtil.refreashOrder(controls2);
    setControls(controls3);
    refreash();
  };
  // 刷新表单子控件
  const refeashChildren = function () {
    const oldControls = ControlUtil.getOldFormControls(children, null);
    const oldcontrolmapref = new Map();
    ControlUtil.controlsToMap(oldControls, oldcontrolmapref);
    const controlmapref = new Map();
    ControlUtil.controlsToMap(controls, controlmapref);
    oldcontrolmapref.forEach((old) => {
      const now = controlmapref.get(old.data.key);
      if (now != null) {
        now.props = old.props;
        if (old.props.designdata != null) {
          now.load(old.props.designdata);
        }
      }
    });
    refreash();
  };
  // 获取后端协议json，后台解析使用
  const getPropertyJson = function () {
    const json = { ...useformData };
    json.controls = [];
    controls.forEach((item) => {
      const c = item.getPropertyJson();
      c == null ? '' : json.controls.push(c);
    });
    return json;
  };
  // 获取前端设计模型json标准
  const getDesignModelJson = function () {
    const json = { ...useformData };
    json.controls = [];
    controls.forEach((item) => {
      const c = item.getDesignModelJson();
      c == null ? '' : json.controls.push(c);
    });
    return json;
  };
  // 获取整个form控件的value值
  const getJsonValue = function () {
    const jsonValues = [];
    controls.forEach((item) => {
      if (item.data.childControls != null) {
        item.getJsonValue(jsonValues);
      } else {
        item.getJsonValue(jsonValues);
      }
    });
    return jsonValues;
  };
  // 设置整个form表单value值 jsonValues:[{key:xxx,value:xxxx}]
  const setJsonValue = function (jsonValues, temp) {
    // console.log(jsonValues);
    (temp?.controls || controls).forEach((item) => {
      item.setJsonValue(jsonValues);
    });
    refreash();
  };
  // 选中控件编辑属性
  const clickControlEditProperty = function (e, control) {
    if (isEditState) {
      refDesignProperty?.current?.setEditProperty('control', control);
    }
  };
  // 移除控件
  const removeControl = function (key) {
    const tempControls = ControlUtil.deepRemoveControl(controls, key);
    setControls(tempControls);
    // 当前属性显示待删控件
    if (refDesignProperty?.current?.selectedControl?.data.key === key) {
      refDesignProperty.current.setEditProperty('form', useformData);
    }
    refreash();
  };
  // 组件内公开开放的form表单接口
  const openObj = function () {
    return {
      getPropertyJson,
      getDesignModelJson,
      isEditState,
      setIsEditState,
      clickControlEditProperty,
      setFormProperty,
      refreash,
      refreshControlsOrder,
      refeashChildren,
      controls,
      useformData,
      getJsonValue,
      setJsonValue,
      getControlByTitle,
      packages,
      eventScripts,
      setEventScripts,
      dataSourceScripts,
      setDataSourceScripts,
      loadDataSource,
      dataSourceResults,
      subForms,
      setSubForms,
      removeControl,
      showControlMenu: (e, ext) => {
        refMenu.current.show(e, ext);
        e.stopPropagation();
      },
      tooldrap,
      toolbar,
      refs: { refDesignProperty, refdatasource, refsubForms, refevent, refDesignHistroy },
    };
  };
  useImperativeHandle(ref, () => openObj());
  // 控件初始化
  useEffect(() => load(), []);
  // 兼容子控件变更刷新
  useEffect(() => refeashChildren(), [children]);
  // form头部工具栏render
  const formToolRender = function () {
    if (formtype !== 2 && subform === 'true') {
      console.warn('formtype不是子表单,被渲染为子表单组件,请改成formtype=1');
    }
    if (subform === 'true') return <></>;
    if (!isEditState) {
      return (
        <Space>
          <Button type="link" onClick={() => setIsEditState(true)}>
            编辑表单
          </Button>
        </Space>
      );
    } else {
      return (
        <Space>
          <Button type="link" onClick={() => save()}>
            {formtype === 2 ? '发布子表单组件' : '保存表单'}
          </Button>
          <Button type="link" onClick={() => refDesignProperty.current.setEditProperty('form', useformData)}>
            配置表单
          </Button>
        </Space>
      );
    }
  };
  // 左侧工具栏render
  const designToolRender = function () {
    return isEditState ? <DesignTool parentForm={openObj()} /> : <></>;
  };
  // 右侧属性栏render
  const designPropertyRender = function () {
    return isEditState ? <DesignProperty ref={refDesignProperty} parentForm={openObj()} /> : <></>;
  };
  // 设计窗体编辑框render
  const designModal = function (content) {
    return isEditState ? (
      <Modal className={"myfullscreen"} visible mask width={10000} closable={false} footer={null}>
        {content}
      </Modal>
    ) : (
      content
    );
  };
  // 显示form元素
  const showFormElement = function (child) {
    return formelement === 'form' ? (
      <Form {...props} layout={useformData.layout}>
        {child}
      </Form>
    ) : (
      <div className={`ant-form ant-form-small ant-form-${useformData.layout}`}>{child}</div>
    );
  };
  return (
    <>
      <DesignContext.Provider value={openObj()}>
        {designModal(
          <Layout style={isEditState?{height: "calc(100vh)"}:{}}>
            {designToolRender()}
            <Layout.Content style={{ padding: 5 }} {...tooldrap.bindDropEndEventProps(openObj())}>
              {formToolRender()}
              {showFormElement(ControlUtil.controlsRender(controls, openObj()))}
              <DesignHistroy ref={refDesignHistroy} formkey={useformData.formkey} />
              <EventScriptList ref={refevent} />
              <DataSourceScriptList ref={refdatasource} />
              <SubFormList ref={refsubForms} />
              <ControlContextMenu ref={refMenu} parentForm={openObj()} />
            </Layout.Content>
            {designPropertyRender()}
          </Layout>,
        )}
      </DesignContext.Provider>
    </>
  );
});
DesignForm.defaultProps = {
  formkey: '', // 表单key
  formtype: 1, // 表单类型:0=主表单,1=扩展表单,2=子表单,表单名称
  formname: '', // 表单名称
  subform: 'false', // 是否是子表单
  formelement: 'form', // 表单元素
  layout: 'horizontal', // 表单默认布局
  initvalue: null, // 默认初始值
  defaultform: null, // 默认表单设计信息
  defaultpackages: null, // 默认编码器支持的包
};
export default DesignForm;
